//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <mantle.h>

// Interface functions
//
PInterface CMutex::Probe(
    /* [in] */ REIID riid)
{
    if (riid == EIID_IInterface) {
        return (PInterface)(IMutex *)this;
    }
    else if (riid == EIID_IMutex) {
        return (IMutex *)this;
    }
    else if (riid == EIID_CLASS_INFO) {
        return (PInterface)&ECLSID_CMutex;
    }
    else if (riid == EIID_INTERFACE_INFO) {
        return (PInterface)&EIID_IMutex;
    }

    return NULL;
}

UInt32 CMutex::AddRef(void)
{
    return (UInt32)m_cRef.Increment();
}

UInt32 CMutex::Release(void)
{
    Int32 nRef = m_cRef.Decrement();

    if (nRef == 0) {
        delete this;
    }
    return (UInt32)nRef;
}

ECode CMutex::Aggregate(
    /* [in] */ AggregateType type,
    /* [in] */ PInterface pObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CMutex::GetDomain(
    /* [out] */ PInterface *ppObj)
{
    return E_NOT_IMPLEMENTED;
}

ECode CMutex::Lock(WaitResult *pResult)
{
    if (NULL == pResult) return E_INVALID_ARGUMENT;

    m_kmutex.Lock(pResult);
    return NOERROR;
}

ECode CMutex::TryLock(
    /* [in] */ Millisecond32 msTimeout,
    /* [out] */ WaitResult *pResult)
{
    if (NULL == pResult) return E_INVALID_ARGUMENT;

    m_kmutex.TryLock(DzMillisecondsToTicks(msTimeout), pResult);
    return NOERROR;
}

ECode CMutex::Unlock()
{
    if (!m_kmutex.IsHeld()) return E_NOT_OWNER;

    m_kmutex.Unlock();
    return NOERROR;
}
